package threads

import database.ConnectionPool
import org.apache.logging.log4j.LogManager
import org.apache.logging.log4j.Logger
import java.sql.Connection
import java.sql.SQLException
import java.util.concurrent.ArrayBlockingQueue

/**
 * 将数据插入到数据库中的线程。该线程会通过死循环以实现“源源不断”。其生命周期与进程相同。
 *
 * @param connectionPool 数据库连接池
 * @param queue 阻塞队列，用于“生产者-消费者”模式的资源沟通
 * @author Jingyu
 */
class InsertThread(
    private val connectionPool: ConnectionPool,
    private val queue: ArrayBlockingQueue<MediaListResponse>
): Thread() {
    private val insertSql = "INSERT INTO video_record(added, aid, view, danmaku, reply, favorite, coin, share, `like`) VALUES (UNIX_TIMESTAMP(),?, ?,?,?,?,?,?,?);"
    private val logger: Logger = LogManager.getLogger(Main::class.java)

    override fun run() {
        while (true) { // 死循环，以实现“源源不断地”
            val connection: Connection = connectionPool.getConnection() // 从数据库连接池里取出来一个连接
            try {
                val mediaListResponse = queue.take() // 从数据队列里取出来一个数据，把它插入到数据库中
                // 将数据批量插入到数据库中
                val preparedStatement = connection.prepareStatement(insertSql)
                for (video in mediaListResponse.data) {
                    preparedStatement.apply {
                        setInt(1, video.id)
                        setInt(2, video.cnt_info.play)
                        setInt(3, video.cnt_info.danmaku)
                        setInt(4, video.cnt_info.reply)
                        setInt(5, video.cnt_info.collect)
                        setInt(6, video.cnt_info.coin)
                        setInt(7, video.cnt_info.share)
                        setInt(8, video.cnt_info.thumbUp)
                    }
                    preparedStatement.addBatch()
                }
                preparedStatement.executeBatch()
                logger.debug("提交插入${mediaListResponse.data.size}条记录完毕")
            } catch (e: SQLException) {
                logger.error("提交插入失败！\n ", e)
            } finally {
                connectionPool.releaseConnection(connection)
            }
        }
    }
}

